home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 140_01.zip / FIXDIR.C < prev    next >
Text File  |  1993-06-26  |  6KB  |  285 lines

  1. /*    FIXDIR.C 22nd Jan 1981
  2.  
  3.     This program will "clean" a CP/M directotry of illegal file
  4.     names. The user is given the option of erasing or renaming
  5.     the illegal file. The program is fast, even on big directories.
  6.     See the accompanying FIXDIR.DOC for a full discussion.
  7.  
  8.     By    Bill Bolton,
  9.         Software Tools,
  10.         P.O. Box 80,
  11.         Newport Beach,
  12.         NSW, 2106
  13.         Australia
  14.  
  15. */
  16.  
  17. #define VERSION 12
  18. #define OPEN 15
  19. #define SEARCH_FIRST 17
  20. #define SEARCH_NEXT 18
  21. #define DELETE 19
  22. #define RENAME 23
  23. #define SETDMA  26
  24. #define SEC_BUF 0X80
  25. #define DEL 0X7F
  26.  
  27. int    space;        /* Count of spaces found in file name */
  28. int    error_count;    /* Count of bad file names found in directory */
  29. int    pass;        /* Number of recursions */
  30. char    drive[1];    /* Storage for drive identifier */
  31.  
  32. main (argc,argv)    /* Search CP/M directory for bad file names */
  33.  
  34. int    argc;
  35. char    *argv[];
  36.  
  37. {
  38.     pass = 0;
  39.     printf("\tFIXDIR version 1.00 \n");
  40.     printf("\t(C) 1981, Software Tools - Sydney, Australia.\n");
  41.     printf("\tCorrects illegal file names in a CP/M disk directory.\n\n");
  42.     dir_check(argc,argv);
  43.     printf("\n\tNo illegal file names in directory on this pass.\n\n");
  44.     if (pass > 1)
  45.         printf("\tThere were %d passes performed.\n",pass);
  46.     exit();
  47. }
  48.  
  49. dir_check(argc,argv)
  50.  
  51. int    argc;
  52. char    *argv[];
  53.  
  54. {
  55.     int    n;
  56.     char    filename[15];
  57.     char    *buf;
  58.     char    fcb1[36];
  59.  
  60.     error_count = 0;        /* Initialise some variables */
  61.     space = 0;
  62.     buf = SEC_BUF;
  63.     pass++;
  64.  
  65.     if (argc > 2){            /* Too many command line args ? */
  66.         command_error(argv[2]);
  67.         }
  68.     strcpy(filename,"");
  69.     strcpy(drive,"");
  70.     if (argc == 2)
  71.         if (strlen(argv[1]) == 2 && isdrive(argv[1])){
  72.             strcpy(filename,argv[1]);
  73.             strcpy(drive,argv[1]);
  74.             }
  75.         else{
  76.             command_error(argv[1]);
  77.         }
  78.     strcat(filename,"????????.???");
  79.     setfcb(fcb1,filename);
  80.     bdos(SETDMA,buf);
  81.     n = bdos(SEARCH_FIRST,fcb1);
  82.     valid_check(n,buf);
  83.     while ((n = bdos(SEARCH_NEXT,fcb1)) != 255){
  84.         if(valid_check(n,buf)){
  85.             while(action(n,buf));
  86.         }
  87.     }
  88.     if (error_count){
  89.         printf("\t\nPerforming another pass.\n\n");
  90.         dir_check(argc,argv);
  91.     }
  92. }
  93.  
  94. /* Checks for legal CP/M drive identifier in range A: through P: */
  95.  
  96. int isdrive(s)
  97.  
  98. char *s;
  99.  
  100. {
  101.     toupper(*s);
  102.     return (*s >= 'A' && *s <= 'P' && *++s == ':');
  103. }
  104.  
  105. /* Checks for legal CP/M directory entry, if illegal entry found prompts
  106.    for erase or rename */
  107.  
  108. int valid_check(n,buf)
  109.  
  110. int    n;
  111. char    *buf;
  112.  
  113. {
  114.     int    i;
  115.  
  116.     if (n == 255)            /* Error indicator from caller */
  117.         return(n);
  118.     buf += (n * 32);
  119.     for (i = 1; i < 12; ++i){
  120.         if (bad_char(i,buf))
  121.             return(-1);
  122.     }
  123.     return(0);
  124. }
  125.  
  126. /* Checks if a character is legal in a CP/M directory entry or file control
  127.    block */
  128.  
  129. int bad_char(i,buf)
  130.  
  131. int    i;
  132. char    *buf;
  133.  
  134. {
  135.     char    temp[0];        /* Transient storage for > del test */
  136.  
  137.     if (i == 1 || i == 9)        /* Reset at start of filename & typ */
  138.         space = 0;         
  139.     switch (buf[i]){
  140.     case  '*':
  141.     case  ',':
  142.     case  '.':
  143.     case  ':':
  144.     case  ';':
  145.     case  '<':
  146.     case  '=':
  147.     case  '>':
  148.     case  '?':
  149.     case  '[':
  150.     case  ']':
  151.     case  DEL:
  152.         return(-1);
  153.     case  ' ':            /* Space is conditionally illegal */
  154.         if (space == 7)        /* Filename is all spaces is a */
  155.             return(-1);    /* definite error */
  156.         space++;        /* Else just keep track of how many */
  157.         return(0);
  158.     }
  159.     if (buf[i] < ' ' || (buf[i] >= 'a' && buf[i] <= 'z'))
  160.         return(-1);
  161.     if (buf[i] > DEL){        /* Bit 7 set may be legal attribute */
  162.         *temp = buf[i] & DEL;     /* so force it to 0 and try again */
  163.         return (bad_char(0,temp));
  164.     }
  165.     else
  166.         return(space);         /* Space preceeding char IS illegal */
  167. }
  168.  
  169. /* Erases or renames a file in CP/M directory */
  170.  
  171. int    action(n,buf)
  172.  
  173. int    n;
  174. char    *buf;
  175.  
  176. {
  177.     char    temp_buf[36];
  178.     char    fcb[36];
  179.     
  180.     buf += (n *32);
  181.     setmem(temp_buf,36,0);
  182.     movmem(buf+1,temp_buf+1,11);
  183.     error_count++;
  184.  
  185.     printf("\07\n\tIllegal CP/M file name : %.8s.%.3s\n\n\07",
  186.         buf+1,buf+9);
  187.     printf("\t%s\n\t\t%s\n\t%s",
  188.         "Press 'E' to erase file",
  189.         "Or",
  190.         "Press 'R' to rename file : ");
  191.     if (toupper(getchar()) == 'E')
  192.         return(erase(temp_buf));
  193.     else
  194.         return(rename(temp_buf));
  195. }
  196.  
  197. /* Erases a file from CP/M directory */
  198.  
  199. int erase(buf)
  200.  
  201. char    *buf;
  202.  
  203. {
  204.     printf("\n\n\tDELETING %.8s.%.3s\n",buf+1,buf+9);
  205.     makefcb(buf,drive);
  206.     if(bdos(DELETE,buf) == 255){
  207.         printf("\07\n\tBDOS DELETE ERROR\n\07");
  208.         return(-1);
  209.     }
  210.     return(0);
  211. }
  212.             
  213. /* Renames a file in  CP/M directory with file name supplied from console */
  214.  
  215. int rename(buf)
  216.  
  217. char    *buf;
  218.  
  219. {
  220.     char    fcb[36];
  221.  
  222.     get_name(fcb);
  223.     if (strlen(drive))
  224.         *fcb = *drive - '@';        /* Put drive into fcb */
  225.     if(bdos(OPEN,fcb) != 255){
  226.         printf("\07\n\tFilename entered ALREADY EXISTS !\n\07");
  227.         return(-1);
  228.     }
  229.     makefcb(buf,drive);
  230.     strcpy(buf+17,fcb+1);
  231.     printf("\n\tRENAMING %.8s.%.3s to %.8s.%.3s\n",
  232.         buf+1,buf+9,buf+17,buf+25);
  233.     if(bdos(RENAME,buf) == 255){
  234.         printf("\07\n\tBDOS RENAME ERROR\n\07");
  235.         return(-1);
  236.     }
  237.     return(0);
  238. }
  239.  
  240. /* Makes a valid CP/M file control block from name supplied from console */
  241.  
  242. int get_name(fcb)
  243.  
  244. char    *fcb;
  245.  
  246. {
  247.     char    new_name[43];        /* Make big for bullet proofing */
  248.  
  249.     printf("\n\n\tEnter new file name :");
  250.     gets(new_name);
  251.     setfcb(fcb,new_name);
  252.     while(valid_check(0,fcb)){
  253.         printf("\07\n\tBAD FILENAME entered as new name !\n\07");
  254.         get_name(fcb);
  255.         }
  256. }
  257.  
  258. /* Makes a CP/M file control block from a CP/M directory entry */
  259.  
  260. int makefcb(buf,ident)
  261.  
  262. char    *buf;
  263. char    *ident;
  264.  
  265. {
  266.     if (strlen(ident))
  267.         *buf = *ident - '@';    /* Put drive into fcb */
  268.     else
  269.         *buf = 0;        /* Use auto disk select */
  270.     setmem(buf+12,24,00);        /* Initialise rest of fcb */
  271. }
  272.  
  273. /* Displays an error message showing incorrect command line argument */
  274.  
  275. int command_error(s)
  276.  
  277. char    *s;
  278.  
  279. {
  280.     printf("\07Command line error : %s\n\n\07",s);
  281.     printf("USAGE :\n\tFIXDIR\n\tFIXDIR B:\n\n");
  282.     printf("\tExiting to CP/M\n");
  283.     exit();
  284. }
  285.